<html>
<head><meta charset="utf-8"><title>Implications of using `slice::as_ptr` for mutable access · wg-secure-code · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/index.html">wg-secure-code</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html">Implications of using `slice::as_ptr` for mutable access</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="216499472"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216499472" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216499472">(Nov 12 2020 at 17:20)</a>:</h4>
<p>So, obviously, <code>slice::as_ptr</code> states that the pointer must not be used for modifying any of the contents of the slice. That's UB and all, very clearly. However, I'm wondering if there are any <em>practical</em> complications if it is used on a <code>&amp;mut [T]</code> instead of the correct <code>as_mut_ptr</code>. Inspect the llvm IR that is generated does not reveal any UB. </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">as_ptr</span><span class="p">(</span><span class="n">slice</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">slice</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">as_mut_ptr</span><span class="p">(</span><span class="n">slice</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">slice</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=28d3c19800236ae520441a22a6f99b19">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=28d3c19800236ae520441a22a6f99b19</a></p>
<p>In particular, the only difference is an additional <code>readonly</code> annotation on the argument/parameter to <code>slice::as_ptr</code> itself. The codegen for the remaining parts of exposed methods is the same. The attribute appears to only add semantics to the method body itself, not place any restrictions on the returned value:</p>
<blockquote>
<p>On a function, this attribute indicates that the function does not<br>
write through any pointer arguments. [https://llvm.org/docs/LangRef.html]</p>
</blockquote>
<p>Since the function itself does not do so, it seems to me like the behavior is defined from llvm IR onwards and everything is fine. This might of course change in future versions of Rust and in other codegen but the current implementation does not appear to make use of it.</p>
<p>I'm wondering because I'm curious how to classify <a href="https://github.com/image-rs/image/issues/1357">https://github.com/image-rs/image/issues/1357</a> in its Advisory</p>



<a name="216511215"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216511215" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tony Arcieri <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216511215">(Nov 12 2020 at 18:51)</a>:</h4>
<p><span class="user-mention" data-user-id="229913">@HeroicKatora</span> seeing some concurrent discussion of this in the Rust Embedded Matrix...</p>



<a name="216511240"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216511240" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tony Arcieri <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216511240">(Nov 12 2020 at 18:51)</a>:</h4>
<p>also paging <span class="user-mention" data-user-id="120791">@RalfJ</span></p>



<a name="216586901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216586901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216586901">(Nov 13 2020 at 09:36)</a>:</h4>
<p><span class="user-mention" data-user-id="229913">@HeroicKatora</span> your quoted code seems wrong, that should be <code>&amp;[u8]</code> for <code>as_ptr</code>. Or maybe I don't understand what that code is supposed to show.</p>



<a name="216587007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216587007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216587007">(Nov 13 2020 at 09:37)</a>:</h4>
<p>and indeed we currently hardly exploit the aliasing guarantees provided by Rust, as LLVM does not have good ways to represent them and MIR optimizations are not far enough along yet</p>



<a name="216587157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216587157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216587157">(Nov 13 2020 at 09:38)</a>:</h4>
<blockquote>
<p>On a function, this attribute indicates that the function does not<br>
write through any pointer arguments. [https://llvm.org/docs/LangRef.html]</p>
</blockquote>
<p>that is the wrong doc. it's for the <code>readonly</code> attribute on functions, not function arguments.</p>



<a name="216587238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216587238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216587238">(Nov 13 2020 at 09:38)</a>:</h4>
<p>but quite possibly LLVM just has no way of saying "this ptr and all its descendants are read-only"</p>



<a name="216589292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216589292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216589292">(Nov 13 2020 at 09:54)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access/near/216586901">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="229913">HeroicKatora</span> your quoted code seems wrong, that should be <code>&amp;[u8]</code> for <code>as_ptr</code></p>
</blockquote>
<p>Indeed that is the crux of the problem. Maybe more clearly what the buggy code was actually doing (it predates TryFrom). All of that hidden in a macro obscuring the target type Wrapper.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">struct</span> <span class="nc">Wrapper</span><span class="p">(</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">4</span><span class="p">]);</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">as_ptr</span><span class="p">(</span><span class="n">slice</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">Wrapper</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// UB according to Rust but how bad does it actually get?</span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="p">(</span><span class="n">slice</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">Wrapper</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>And I'm trying to judge potential implications of that with regards to the AdvisoryDB labels. Unless any miscompilation can be observed I'd feel rather odd about labelling this an exploitable issue of memory safety given if it stays within Rust's provenance model and doesn't even escape  into llvm IR issues</p>



<a name="216589762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216589762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216589762">(Nov 13 2020 at 09:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access/near/216587157">said</a>:</p>
<blockquote>
<blockquote>
<p>On a function, this attribute indicates that the function does not<br>
write through any pointer arguments. [https://llvm.org/docs/LangRef.html]</p>
</blockquote>
<p>that is the wrong doc. it's for the <code>readonly</code> attribute on functions, not function arguments.</p>
</blockquote>
<p>Curious, there are no docs for the function attribute itself that I can find but clearly those attributes exist since the API reference shows them accessible in C++ (Argument::onlyReadsMemory: <code>Return true if this argument has the readonly or readnone attribute.</code>) and they get printed in the llvm IR dump (unless I'm serious misinterpreting what those attributes apply to):</p>
<div class="codehilite"><pre><span></span><code>define i8* @&quot;_ZN4core5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$6as_ptr17hd73c4c18f8974eb1E&quot;([0 x i8]* noalias nonnull readonly align 1 %self.0, i64 %self.1) unnamed_addr #0 !dbg !29
</code></pre></div>



<a name="216725946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216725946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216725946">(Nov 14 2020 at 12:18)</a>:</h4>
<p>The docs say this:</p>
<blockquote>
<p>On an argument, this attribute indicates that the function does not write through this pointer argument, even though it may write to the memory that the pointer points to.</p>
</blockquote>



<a name="216725953"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216725953" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216725953">(Nov 14 2020 at 12:19)</a>:</h4>
<p><span class="user-mention" data-user-id="229913">@HeroicKatora</span>  These seem like the relevant docs for the argument attribute case.</p>



<a name="216727192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216727192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216727192">(Nov 14 2020 at 12:43)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> Thanks for the find. I suppose this means the interpretation in llvm IR already does not exhibit UB as the attribute is effectively irrelevant after the call, when used later. I'm probably going to file it as only an informational advisory then.</p>



<a name="216728585"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146229-wg-secure-code/topic/Implications%20of%20using%20%60slice%3A%3Aas_ptr%60%20for%20mutable%20access/near/216728585" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146229-wg-secure-code/topic/Implications.20of.20using.20.60slice.3A.3Aas_ptr.60.20for.20mutable.20access.html#216728585">(Nov 14 2020 at 13:14)</a>:</h4>
<p>Yeah that is my interpretation, too -- this is UB, but I see currently no way that it could lead to unexpected behavior.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>